Passed
Push — master ( 1af5bf...eabd18 )
by thomas
05:56
created

validation.test.js ➔ describe(ꞌChainPathBuilderꞌ)   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 88

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
c 1
b 0
f 0
nc 1
dl 0
loc 88
rs 8.6012
nop 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
var jsrsasign = require('jsrsasign');
2
var assert = require('assert');
3
var bip70 = require('../main.js');
4
var PaymentRequest = bip70.ProtoBuf.PaymentRequest;
5
var ChainPathValidator = bip70.X509.ChainPathValidator;
6
var ChainPathBuilder = bip70.X509.ChainPathBuilder;
7
var certfile = require("./certfile");
8
9
10
function addDays(date, days) {
11
    var result = new Date(date);
12
    result.setDate(result.getDate() + days);
13
    return result;
14
}
15
16
function subDays(date, days) {
17
    var result = new Date(date);
18
    result.setDate(result.getDate() - days);
19
    return result;
20
}
21
22
function certFromEncoding(data, encoding) {
23
    var b = Buffer.from(data, encoding);
24
    var cert = new jsrsasign.X509();
25
    cert.readCertHex(b.toString('hex'));
26
    return cert;
27
}
28
29
describe("GetSignatureAlgorithm", function() {
30
    var entityCert = certFromEncoding(certfile.test_cert.entityCertificate, "base64");
31
32
    it("Deals with RSA public keys", function(cb) {
33
        var sha256 = bip70.X509.GetSignatureAlgorithm(entityCert, bip70.X509.PKIType.X509_SHA256);
34
        assert.equal(sha256, "SHA256withRSA");
35
36
        var sha1 = bip70.X509.GetSignatureAlgorithm(entityCert, bip70.X509.PKIType.X509_SHA1);
37
        assert.equal(sha1, "SHA1withRSA");
38
        cb();
39
    });
40
41
    it("Deals with ECDSA public keys (mocked)", function(cb) {
42
        var mockKey = {};
43
        mockKey.getPublicKey = function() {
44
            return {
45
                type: "ECDSA"
46
            };
47
        };
48
49
        var sha256 = bip70.X509.GetSignatureAlgorithm(mockKey, bip70.X509.PKIType.X509_SHA256);
50
        assert.equal(sha256, "SHA256withECDSA");
51
52
        var sha1 = bip70.X509.GetSignatureAlgorithm(mockKey, bip70.X509.PKIType.X509_SHA1);
53
        assert.equal(sha1, "SHA1withECDSA");
54
        cb();
55
    });
56
57
    it("Rejects unknown PKI types", function(cb) {
58
        var mockKey = {};
59
        mockKey.getPublicKey = function() {
60
            return {
61
                type: "ECDSA"
62
            };
63
        };
64
65
        assert.throws(function() {
66
            bip70.X509.GetSignatureAlgorithm(mockKey, "unknown");
67
        }, "Unknown PKI type or no signature algorithm specified.");
68
69
        assert.throws(function() {
70
            bip70.X509.GetSignatureAlgorithm(mockKey, bip70.X509.PKIType.NONE);
71
        }, "Unknown PKI type or no signature algorithm specified.");
72
73
        cb();
74
    });
75
76
    it("Rejects unknown public key type", function(cb) {
77
        var mockKey = {};
78
        mockKey.getPublicKey = function() {
79
            return {
80
                type: "wut"
81
            };
82
        };
83
84
        assert.throws(function() {
85
            bip70.X509.GetSignatureAlgorithm(mockKey, "unknown");
86
        }, "Unknown public key type");
87
88
        cb();
89
    });
90
});
91
92
describe('ChainPathBuilder', function() {
93
    var fixture = certfile.test_cert;
94
    var entityCert = certFromEncoding(fixture.entityCertificate, "base64");
95
    var rootCert = certFromEncoding(fixture.rootCertificate, "base64");
96
    var intermediates = fixture.intermediates.map(function(base64) {
97
        return certFromEncoding(base64, "base64");
98
    });
99
    var chainValidTime = fixture.chainValidTime;
100
101
    it('builds a valid certificate chain', function(cb) {
102
        var numCerts = 2 + intermediates.length;
103
        var builder = new ChainPathBuilder([rootCert]);
104
        var path = builder.shortestPathToTarget(entityCert, intermediates);
105
106
        assert.equal(path.length, numCerts, "expecting " + numCerts + " certificates in total for path");
107
108
        var validator = new ChainPathValidator({
109
            currentTime: chainValidTime
110
        }, path);
111
112
        assert.doesNotThrow(function() {
113
            validator.validate();
114
        }, 'no errors expected during validation');
115
116
        cb();
117
    });
118
119
    function testCertificateValidity(now) {
120
        var builder = new ChainPathBuilder([rootCert]);
121
        var path = builder.shortestPathToTarget(entityCert, intermediates);
122
        assert.equal(path.length, 3, "expecting 3 certificates in total for path");
123
124
        var validator = new ChainPathValidator({
125
            currentTime: now
126
        }, path);
127
128
        var err;
129
        try {
130
            validator.validate();
131
        } catch (e) {
132
            err = e;
133
        }
134
135
        assert.ok(typeof err === "object");
136
        assert.equal(err.message, "Certificate is not valid");
137
    }
138
139
    [rootCert].concat(intermediates).concat(entityCert).map(function(cert, i) {
140
        it('rejects if `now` is after #' + i + ' certs `notAfter`', function(cb) {
141
            // this timestamp conflicts with the root certificates notBefore
142
            var now = jsrsasign.zulutodate(cert.getNotAfter());
143
            now = addDays(now, 2);
144
            testCertificateValidity(now);
145
            cb();
146
        });
147
148
        it('rejects if `now` is before #' + i + ' certs `notBefore`', function(cb) {
149
            // this timestamp conflicts with the root certificates notBefore
150
            var now = jsrsasign.zulutodate(rootCert.getNotBefore());
151
            now = subDays(now, 2);
152
            testCertificateValidity(now);
153
            cb();
154
        });
155
    });
156
157
    function testNoCertificationPath(trusted, intermediate, end) {
158
        var err;
159
        try {
160
            var builder = new ChainPathBuilder(trusted);
161
            builder.shortestPathToTarget(end, intermediate);
162
        } catch (e) {
163
            err = e;
164
        }
165
166
        assert.equal(typeof err, "object");
167
        assert.equal(err.message, "No certificate paths found");
168
    }
169
170
    it('errors if intermediate certificate is missing', function(cb) {
171
        testNoCertificationPath([rootCert], [], entityCert);
172
        cb();
173
    });
174
175
    it('errors if root certificate is missing', function(cb) {
176
        testNoCertificationPath([], intermediates, entityCert);
177
        cb();
178
    });
179
});
180
181
describe("RequestValidator", function() {
182
    describe("validateSignature", function() {
183
        var i = 0;
184
        certfile.test_cert.requests.map(function(request) {
185
            it("works with a test fixture " + i, function(cb) {
186
                var time = request.time;
187
                var request64 = request.request;
188
                var req = PaymentRequest.decode(Buffer.from(request64, 'base64'));
189
                var root = certFromEncoding(certfile.test_cert.rootCertificate, "base64");
190
                var intermediates = certfile.test_cert.intermediates.map(function(cert) {
191
                    return certFromEncoding(cert, "base64");
192
                });
193
                var entityCert = certFromEncoding(certfile.test_cert.entityCertificate, "base64");
194
                var validator = new bip70.X509.RequestValidator({
195
                    trustStore: [root],
196
                    currentTime: time
197
                });
198
199
                assert.doesNotThrow(function() {
200
                    validator.validateCertificateChain(entityCert, intermediates);
201
                }, "should validate certificate chain");
202
203
                assert.doesNotThrow(function() {
204
                    validator.validateSignature(req, entityCert);
205
                }, "should validate request signature");
206
207
                var path = [];
208
                assert.doesNotThrow(function() {
209
                    path = validator.verifyX509Details(req);
210
                }, "full validation should succeed");
211
212
                assert.equal(path.length, 1 + intermediates.length + 1);
213
                cb();
214
            });
215
            i++;
216
        });
217
218
        var request = certfile.test_cert.requests[0];
219
        it("rejects an invalid signature", function(cb) {
220
            var time = request.time;
221
            var request64 = request.request;
222
            var req = PaymentRequest.decode(Buffer.from(request64, 'base64'));
223
            var root = certFromEncoding(certfile.test_cert.rootCertificate, "base64");
224
            var entityCert = certFromEncoding(certfile.test_cert.entityCertificate, "base64");
225
            var validator = new bip70.X509.RequestValidator({
226
                trustStore: [root],
227
                currentTime: time
228
            });
229
230
            req.signature = Buffer.from("dZmjw+Tg7ssFmBF3gqbHvyImTEZ6ffMYMBTAFiJs0RnpY9bPCzEILbCX6rBeagffaShqmkyn0iU3+h509Ul8rtPbR+C4c26uFJNLMXWbq7QiiIbpwCaJjtQFXipm7bgVlv+swrMTVu/K+atAsY8INUyuE/CrV53fN7P9gKFqlmlMB2MdrN/oFCx2dDWooXIjvl11hJDkae+r3bC+YCMBfe3MFCDpmF/c3+0xkFrw2R7cZLdUu+kBF3iHL0ezslxKJLtYMb1cuc5DWiGbVOZqu/+Gt3Pul3DS7Tk8QNx7ou1As0EiGWc+BKxUm63lNS/JlIUwvx6A+q0nnu7WDA28Hg==", "base64");
231
            assert.ok(false === validator.validateSignature(req, entityCert));
232
233
            assert.throws(function() {
234
                validator.verifyX509Details(req);
235
            }, "Invalid signature on request");
236
237
            cb();
238
        });
239
    });
240
241
});
242